package com.sql.test.activity;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.R;
import com.location.test.LocationService;
import com.sql.test.service.DataFormatService;
import com.sql.test.service.LocalDatabaseSerivce;
import com.worldwind.test.LocalDigitializeFeatureActivity;
import com.worldwind.test.GeometryCreator;
import com.worldwind.test.PickObjectController;

import java.util.ArrayList;
import java.util.Iterator;

import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.WorldWindow;
import gov.nasa.worldwind.geom.Camera;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.globe.BasicElevationCoverage;
import gov.nasa.worldwind.globe.Globe;
import gov.nasa.worldwind.layer.BackgroundLayer;
import gov.nasa.worldwind.layer.BlueMarbleLandsatLayer;
import gov.nasa.worldwind.layer.Layer;
import gov.nasa.worldwind.layer.LayerList;
import gov.nasa.worldwind.layer.RenderableLayer;
import gov.nasa.worldwind.layer.TiandituCia_cLayer;
import gov.nasa.worldwind.layer.TiandituCva_cLayer;
import gov.nasa.worldwind.layer.TiandituImg_cLayer;
import gov.nasa.worldwind.layer.TiandituVec_cLayer;
import gov.nasa.worldwind.shape.Label;
import gov.nasa.worldwind.shape.Path;
import gov.nasa.worldwind.shape.Placemark;
import gov.nasa.worldwind.shape.Polygon;

/**
 * Created by Lenovo on 2018/4/22.
 */

public class AttributeSqlActivity  extends AppCompatActivity implements  NavigationView.OnNavigationItemSelectedListener{



    //part1:导航栏设计
    //选项菜单弹出对话框属性
    protected String aboutBoxTitle = "World Wind Cumpus";        // TODO: use a string resource, e.g., app name

    protected String aboutBoxText = "A controller of layers";    // TODO: make this a string resource
    //工具条中添加图层导航栏

    protected static int selectedItemId ;

    protected ActionBarDrawerToggle drawerToggle;

    protected NavigationView navigationView;



    //part2:数据查询
    /**
     * This protected member allows derived classes to override the resource used in setContentView.
     */
    protected int layoutResourceId = R.layout.attribute_sql;

    /**
     * The WorldWindow (GLSurfaceView) maintained by this activity
     */
    protected WorldWindow wwd;

    /**attribute sql
      step 1: get tables and store selected
      step 2: get columns,especially geometry column ,and store them
      step 3: get column value ,and sotre it
      step 4: search feature data by sql
      step 5: convert geometry data format
      step 5: draw feature on globle
    */
    //store variables
    private ArrayList<String> tables = new ArrayList<>();
    private ArrayList<String> columns = new ArrayList<>();
    private ArrayList<String> values = new ArrayList<>();
    private String geometryColumn = new String();
    private String selectedTable = null;
    private String selectedCoulmn = null;
    private String selectedValue = null;

    //store feature result data
    private ArrayList<String[]> featuresData = new ArrayList<>();

    //view controller
    private CheckBox checkSql = null;
    private EditText tableEditText = null;
    private EditText columnEditText = null;
    private EditText valueEditText = null;
    private ListView tablesListView = null;
    private ListView columnsListView = null;
    private ListView valuesListView = null;
    private Button btnSearch = null;
    //use to toggle search to input activity:进行记录与查询界面的转换
    Button btnToggleInput = null;
    //use DatabaseService
    private LocalDatabaseSerivce databaseSerivce = new LocalDatabaseSerivce();
    //use data format convert service
    private DataFormatService dataFormatService = new DataFormatService();
    //geometry creator
    private GeometryCreator geometryCreator = new GeometryCreator();

    //show result feature layer
    private RenderableLayer resultLayer = new RenderableLayer();
    //
    private  RenderableLayer labelsLayer = new RenderableLayer();
    //add pickObject Controller
    private PickObjectController pickObjectController=null;

    //进行定位的服务
    LocationService locationService =null;
    RenderableLayer locationLayer = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Establish the activity content
        setContentView(this.layoutResourceId);
        this.setTitle("信息查询（本地）");
        //initial view controller
        checkSql = (CheckBox)findViewById(R.id.checkSql);
        tableEditText = (EditText)findViewById(R.id.selectTable);
        columnEditText = (EditText)findViewById(R.id.selectColumn);
        valueEditText = (EditText)findViewById(R.id.selectValue);
        tablesListView = (ListView)findViewById(R.id.tables);
        columnsListView = (ListView)findViewById(R.id.columns);
        valuesListView = (ListView)findViewById(R.id.values);
        btnSearch = (Button)findViewById(R.id.search);
        // toggle to Input view:转换到输入界面
        btnToggleInput = (Button)findViewById(R.id.toggleInput);
        // Create the World Window (a GLSurfaceView) which displays the globe.
        this.wwd = new WorldWindow(this);
        //add pickObject Controller
        pickObjectController = new PickObjectController(this);
        this.wwd.setWorldWindowController(pickObjectController);
        // Add the WorldWindow view object to the layout that was reserved for the globe.
        FrameLayout globeLayout = (FrameLayout) findViewById(R.id.globe);
        globeLayout.addView(this.wwd);

        // Setup the World Window's layers.
        this.wwd.getLayers().addLayer(new BackgroundLayer());
        this.wwd.getLayers().addLayer(new BlueMarbleLandsatLayer());
        // Setup the World Window's elevation coverages.
        this.wwd.getGlobe().getElevationModel().addCoverage(new BasicElevationCoverage());

        //add init map service:添加初始的地图服务
        Layer layer = new TiandituImg_cLayer();
        layer.setDisplayName(getText(R.string.tiandituImgLayerName).toString());
        this.wwd.getLayers().addLayer(layer);

        //add result layer to wwd
        this.wwd.getLayers().addLayer(resultLayer);
        //add label layer:添加标注
        this.wwd.getLayers().addLayer(labelsLayer);
        //copy database file to external directory
        databaseSerivce.loadLocalDB(this);

        //添加图层导航栏
        onCreateDrawer();

        //用于切换学校区域和全球显示视图
        FloatingActionButton codeViewButton = (FloatingActionButton) findViewById(R.id.fab);
        codeViewButton.setVisibility(View.VISIBLE);    // is set to GONE in layout
        codeViewButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //判断当前是区域显示还是全球显示
                if (wwd.getNavigator().getAltitude()>10e4){
                    //如果是全球显示，转换到学校区域视图
                    Globe globe = getWorldWindow().getGlobe();
                    Camera camera = new Camera();
                    camera.set(35.94, 120.17, 2500, WorldWind.ABSOLUTE, 0, 0, 0.0 /*roll*/);
                    getWorldWindow().getNavigator().setAsCamera(globe, camera);
                    wwd.requestRedraw();
                }else{
                    // 如果是区域显示，转换到全球视图
                    Globe globe = getWorldWindow().getGlobe();
                    Camera camera = new Camera();
                    camera.set(35.94, 120.17, 10e6, WorldWind.ABSOLUTE, 0, 0, 0.0 /*roll*/);
                    getWorldWindow().getNavigator().setAsCamera(globe, camera);
                    wwd.requestRedraw();
                }
            }
        });

        //定位服务
        locationLayer = new RenderableLayer();
        wwd.getLayers().addLayer(locationLayer);
        locationService= new LocationService(this,wwd,locationLayer);
        locationService.startLocation();
    }

    @Override
    protected void onStart() {
        super.onStart();
        //add view listener
        checkSql.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked){
                    //initial tablesListView data by select tables from db
                  tables = databaseSerivce.selectTablesName(getApplicationContext());
                  ListAdapter listAdapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.attribute_item,tables);
                  tablesListView.setAdapter(listAdapter);
                }
            }
        });
        tableEditText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tablesListView.setVisibility(View.VISIBLE);
            }
        });
        tablesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectedTable =tablesListView.getItemAtPosition(position).toString();
                tableEditText.setText(selectedTable);
                //hide tablesListView after finish selecting item
                tablesListView.setVisibility(View.INVISIBLE);
                //select columns by selectedTableName
                columns = databaseSerivce.selectCoulmnsName(getApplicationContext(),selectedTable);
                geometryColumn = databaseSerivce.getGeometryColumn();
                //add column data to columnListView
                ListAdapter listAdapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.attribute_item,columns);
                columnsListView.setAdapter(listAdapter);
            }
        });
        columnEditText.setOnClickListener(new  View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    columnsListView.setVisibility(View.VISIBLE);
            }
        });
        columnsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    String tempSelectedCoulmn = columnsListView.getItemAtPosition(position).toString();
                    columnEditText.setText(tempSelectedCoulmn);
                    columnsListView.setVisibility(View.INVISIBLE);
                    //select column values by given column
                    values = databaseSerivce.selectColumnValues(getApplicationContext(),selectedTable,tempSelectedCoulmn);
                    //add values data to valuesListView
                    ListAdapter listAdapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.attribute_item,values);
                    valuesListView.setAdapter(listAdapter);
            }
        });
        valueEditText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    valuesListView.setVisibility(View.VISIBLE);
            }
        });
        valuesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String tempSelectedValue = valuesListView.getItemAtPosition(position).toString();
                valueEditText.setText(tempSelectedValue);
                valuesListView.setVisibility(View.INVISIBLE);
            }
        });
        btnSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //get text while it change by write instead of choose
                //避免先进行了记录条件查询，再清空editview进行记录全查询时，条件依旧的情况,需要从editview中重新获取值
                //而selectedTable不管是何种查询都需要，而且不允许编辑，故而不需要重新获取
                //if no text in editview,we will get String ""
                    selectedCoulmn = columnEditText.getText().toString();
                    selectedValue = valueEditText.getText().toString();
                try {
                    //select features data by given condition
                    featuresData = databaseSerivce.selectFeatureData(getApplicationContext(), selectedTable, selectedCoulmn, selectedValue, columns, geometryColumn);
                }catch (Exception e){
                    //selectedTable shouldn't be null
                    Toast.makeText(getApplicationContext(),"数据查询异常："+e,Toast.LENGTH_SHORT).show();
                }
                String geomText ,geomType = null;
                ArrayList<Position> positions = null;
                ArrayList<Position[]> multiPositions = null;
                //feature number
                if(featuresData!=null) {
                    int featureNum = featuresData.size();
                    for (int i = 0; i < featureNum; i++) {
                        //convert geometry data  text  format to digit
                        geomText = featuresData.get(i)[featuresData.get(i).length - 1];
                        //由于数据插入问题，或其他原因，空间数据为null的异常处理
                        if (geomText == null) {
                            geomType = "NONE";
                        } else {
                            geomType = dataFormatService.getGeomType(geomText);
                        }
                        //get atttibute number which used to limit loop
                        int attributeNum = featuresData.get(i).length - 1;
                        Placemark placemark = null;
                        Path polyline = null;
                        Polygon polygon = null;
                        //draw feature by selected feature data
                        switch (geomType) {
                            case "POINT":
                                //由一个图形组成，图形由一个点构成，点包含xy坐标
                                positions = dataFormatService.getPositions(geomText);
                                placemark = geometryCreator.createPlacemark(positions.get(0), featuresData.get(i)[0]);
                                Label placemarklabel = geometryCreator.createLabel(positions.get(0), featuresData.get(i)[1]);
                                //add attributes to feature except geometry attribute
                                attributeNum = featuresData.get(i).length - 1;
                                for (int j = 0; j < attributeNum; j++) {
                                    placemark.putUserProperty(columns.get(j), featuresData.get(i)[j]);
                                }

                                resultLayer.addRenderable(placemark);
                                labelsLayer.addRenderable(placemarklabel);
                                wwd.requestRedraw();
                                break;
                            case "LINESTRING":
                                //由一个图形组成，图形由多个点构成，每个点包含xy坐标
                                positions = dataFormatService.getPositions(geomText);
                                polyline = geometryCreator.createPolyline(positions);
                                //add attributes to feature except geometry attribute
                                attributeNum = featuresData.get(i).length - 1;
                                for (int j = 0; j < attributeNum; j++) {
                                    polyline.putUserProperty(columns.get(j), featuresData.get(i)[j]);
                                }
                                resultLayer.addRenderable(polyline);
                                wwd.requestRedraw();
                                break;
                            case "POLYGON":
                                //由一个图形组成，图形由多个点构成，每个点包含xy坐标,POLYGON((,,)),格式与LINESTRING(,,)有所不同
                                multiPositions = dataFormatService.getMultiPositions(geomText);
                                positions = new ArrayList<>();
                                int pointNum = multiPositions.get(0).length;
                                for (int m = 0; m < pointNum; m++) {
                                    positions.add(multiPositions.get(0)[m]);
                                }
                                polygon = geometryCreator.createPolygon(positions);
                                //add attributes to feature except geometry attribute
                                attributeNum = featuresData.get(i).length - 1;
                                for (int j = 0; j < attributeNum; j++) {
                                    polygon.putUserProperty(columns.get(j), featuresData.get(i)[j]);
                                }
                                resultLayer.addRenderable(polygon);
                                wwd.requestRedraw();
                                break;
                            case "MULTIPOINT":
                                //由多个图形组成，每个图形包含一个点，每个点包含xy坐标
                                positions = dataFormatService.getPositions(geomText);
                                int pointsNumber = positions.size();
                                for (int k = 0; k < pointsNumber; k++) {
                                    placemark = geometryCreator.createPlacemark(positions.get(k), featuresData.get(i)[0]);
                                    //add attributes to feature except geometry attribute
                                    attributeNum = featuresData.get(i).length - 1;
                                    for (int j = 0; j < attributeNum; j++) {
                                        placemark.putUserProperty(columns.get(j), featuresData.get(i)[j]);
                                    }
                                    resultLayer.addRenderable(placemark);
                                }
                                wwd.requestRedraw();
                                break;
                            case "MULTILINESTRING":
                                //由多个图形组成，每个图形又由多个点构成，每个点包含xy坐标
                                multiPositions = dataFormatService.getMultiPositions(geomText);

                                for (int k = 0; k < multiPositions.size(); k++) {
                                    positions = new ArrayList<>();
                                    int pointNumber = multiPositions.get(k).length;
                                    for (int m = 0; m < pointNumber; m++) {
                                        positions.add(multiPositions.get(k)[m]);
                                    }
                                    polyline = geometryCreator.createPolyline(positions);
                                    //add attributes to feature except geometry attribute
                                    attributeNum = featuresData.get(i).length - 1;
                                    for (int j = 0; j < attributeNum; j++) {
                                        polyline.putUserProperty(columns.get(j), featuresData.get(i)[j]);
                                    }
                                    resultLayer.addRenderable(polyline);
                                }
                                wwd.requestRedraw();
                                break;
                            case "MULTIPOLYGON":
                                //由多个图形组成，每个图形又由多个点构成，每个点包含xy坐标
                                multiPositions = dataFormatService.getMultiPositions(geomText);
                                for (int k = 0; k < multiPositions.size(); k++) {
                                    positions = new ArrayList<>();
                                    int pointNumber = multiPositions.get(k).length;
                                    for (int m = 0; m < pointNumber; m++) {
                                        positions.add(multiPositions.get(k)[m]);
                                    }
                                    polygon = geometryCreator.createPolygon(positions);
                                    //add attributes to feature except geometry attribute
                                    attributeNum = featuresData.get(i).length - 1;
                                    for (int j = 0; j < attributeNum; j++) {
                                        polygon.putUserProperty(columns.get(j), featuresData.get(i)[j]);
                                    }
                                    resultLayer.addRenderable(polygon);
                                }
                                wwd.requestRedraw();
                                break;
                            case "NONE":
                                Toast.makeText(getApplicationContext(), "空间数据为空，查询失败！", Toast.LENGTH_SHORT).show();
                                break;
                        }
                    }
                    //显示到查询的要素位置
                    if (positions.size() > 0) {
                        Globe globe = getWorldWindow().getGlobe();
                        Camera camera = new Camera();
                        camera.set(positions.get(0).latitude, positions.get(0).longitude, 2500, WorldWind.ABSOLUTE, 0, 0, 0.0 /*roll*/);
                        getWorldWindow().getNavigator().setAsCamera(globe, camera);
                        wwd.requestRedraw();
                    }
                }
            }
        });

        btnToggleInput.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), LocalDigitializeFeatureActivity.class);
                startActivity(intent);
            }
        });

    }

    @Override
    protected void onPause() {
        super.onPause();
        this.wwd.onPause(); // pauses the rendering thread
    }

    @Override
    protected void onResume() {
        super.onResume();
        this.wwd.onResume(); // resumes a paused rendering thread
    }

    //添加工具条中的选项菜单，about
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //选项菜单
        this.getMenuInflater().inflate(R.menu.about_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        //如果点击了选项菜单，将显示相应的选项信息
        int id = item.getItemId();
        if (id == R.id.action_about) {
            showAboutBox();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    /**
     * This method is invoked when the About button is selected in the Options menu.
     */
    protected void showAboutBox() {
        //选项菜单被点击后，显示简单信息提示对话框
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
        alertDialogBuilder.setTitle(this.aboutBoxTitle);
        alertDialogBuilder
                .setMessage(this.aboutBoxText)
                .setCancelable(true)
                .setNegativeButton("Close", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // if this button is clicked, just close
                        // the dialog box and do nothing
                        dialog.cancel();
                    }
                });

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();
    }


    //导航监听及方法
    protected void onCreateDrawer() {
        // Add support for a Toolbar and set to act as the ActionBar
        Toolbar toolbar = (Toolbar) this.findViewById(R.id.toolbar);
        /*此处抛出该异常： if (ab instanceof WindowDecorActionBar) {
        throw new IllegalStateException("This Activity already has an action bar supplied " +
                "by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set " +
                 "windowActionBar to false in your theme to use a Toolbar instead.");
        }*/
        //解决方案：设置toolbar的theme,添加style theme资源
        // android:theme="@style/AppTheme.PopupOverlay"
        //关键在于设置Manifest.xml中，设置activity的theme>>android:theme="@style/AppTheme.NoActionBar">
        this.setSupportActionBar(toolbar);

        // Add support for the navigation drawer full of examples
        //The DrawerLayout to link to the given Activity's ActionBar
        DrawerLayout drawer = (DrawerLayout) this.findViewById(R.id.drawer_layout);

        this.drawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(this.drawerToggle);
        this.drawerToggle.syncState();
        //添加导航栏监听
        this.navigationView = (NavigationView) this.findViewById(R.id.nav_view);
        this.navigationView.setNavigationItemSelectedListener(this);
        this.navigationView.setCheckedItem(selectedItemId);
    }



    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        // Persist the selected item between Activities
        selectedItemId = item.getItemId();

        // Handle navigation view item clicks here.
        switch (selectedItemId) {
            case R.id.TiandituVecLayer:
                //需要允许网络访问，设置manifest中的网络权限，否则无法加载在线服务
                loadLayer(new TiandituVec_cLayer(),R.string.tiandituVecLayerName);
                break;
            case R.id.TiandituImgLayer:
                loadLayer(new TiandituImg_cLayer(), R.string.tiandituImgLayerName);
                break;
            case R.id.TiandituCvaLayer:
                loadLayer(new TiandituCva_cLayer(), R.string.tiandituCvaLayerName);
                break;
            case R.id.TiandituCiaLayer:
                loadLayer(new TiandituCia_cLayer(), R.string.tiandituCiaLayerName);
                break;
        }
        //自动隐藏
        DrawerLayout drawer = (DrawerLayout) this.findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }



    public void  loadLayer(Layer layer, int layerName){
        this.setTitle(layerName);
        layer.setDisplayName(this.getText(layerName).toString());
        //根据图层名删除已经加载的图层，避免重复加载,
        LayerList layerList = this.wwd.getLayers();
        Iterator<Layer> iterator = layerList.iterator();
        Layer previousLayer = null;
        while (iterator.hasNext()){
            Layer currentlayer = iterator.next();
            if(currentlayer.getDisplayName()!=null) {
                if (currentlayer.getDisplayName().equals(this.getText(layerName).toString())) {
                    previousLayer = currentlayer;
                }
            }
        }
        //如果图层已存在，删除后加载到当前顶层
        if(previousLayer!=null) {
            this.wwd.getLayers().removeLayer(previousLayer);
        }
        //加载图层
        this.wwd.getLayers().addLayer(layer);
        //重绘
        this.wwd.requestRedraw();
    }

    public WorldWindow getWorldWindow() {
        return this.wwd;
    }

}
